package org.biogroovy.search;

import org.biogroovy.search.eutils.PubMedSearchEngine;

/**
 * This factory is responsible for creating instances of the SearchEngine implementations.
 */
public class SearchEngineFactory {
	
	/**
	 * A map of search engine classes and their names.
	 */
	static SortedMap<String, ISearchEngine> searchEngineMap = new TreeMap<String, ISearchEngine>();
	
	/**
	 * A list of the available search engine names
	 */
	static List<String> searchEngineNames = new ArrayList<>();
	
	static {
		ISearchEngine engine = new PubMedSearchEngine();
		searchEngineMap.put(engine.getName(),engine);	
		searchEngineNames.addAll(searchEngineMap.keySet());
	}
	
	
	/**
	 * This method gets an instance of a search engine 
	 * @param name  The name of the search engine.
	 * @return  The selected search engine.
	 */
	public static ISearchEngine getInstance(String name){
		ISearchEngine enginePrototype = searchEngineMap.get(name);
		if (enginePrototype == null){
			throw new IllegalArgumentException("Unknown search engine: " + name);
		}
		Class<?> clazz = enginePrototype.getClass();
		
		return createSearchEngine(clazz);		
	}
	

	
	/**
	 * This method gets a list of registered search engine names.
	 * @return a list of search engine names.
	 */
	public static List<String> getSearchEngineNames(){
		return searchEngineNames;
	}
	
	/**
	 * This method gets a list of registered search engines.
	 * @return  a list of search engines.
	 */
	public static List<ISearchEngine> getSearchEngines(){
		List<ISearchEngine> searchEngines = new ArrayList<ISearchEngine>();
		for(ISearchEngine engine : searchEngineMap.values()){
			Class<?> clazz = engine.getClass();
			searchEngines.add(createSearchEngine(clazz));
		}
		return searchEngines;
	}
	
	/**
	 * This method creates instances of search engines based on the specified class.
	 * @param clazz	The search engine class (must implement the SearchEngine interface)
	 * @return
	 */
	private static createSearchEngine(Class<?> clazz){
		
		ISearchEngine searchEngine = null;
		try {
			searchEngine = (ISearchEngine)clazz.newInstance();
		} catch (Exception ce){
			ce.printStackTrace();
		}
		return searchEngine;
	}

}
